<template>
    <div class="role-container">
        <el-card shadow="never">
            <el-form @submit.prevent inline class="search-form">
                <el-form-item label="用户名" size="default">
                    <el-input
                        v-model="roleName"
                        placeholder="请输入角色名"
                        size="default"
                        @keyup.enter="handleQuery"
                    ></el-input>
                </el-form-item>
                <el-form-item size="default">
                    <el-button
                        type="primary"
                        @click="handleRemoveRoleNameQuery"
                    >
                        重置
                    </el-button>
                    <el-button
                        icon="Search"
                        type="primary"
                        :disabled="!roleName"
                        @click="handleQuery"
                    >
                        搜索
                    </el-button>
                </el-form-item>
            </el-form>
        </el-card>
        <el-card shadow="never">
            <el-button type="primary" icon="Plus" @click="dialogVisible = true">
                添加角色
            </el-button>
            <el-table
                :data="roleTableData"
                border
                stripe
                :show-overflow-tooltip="true"
                max-height="430px"
                tooltip-effect="dark"
                style="margin-top: 10px"
            >
                <el-table-column label="序号" width="100">
                    <template #default="{ $index }">
                        {{ $index + 1 }}
                    </template>
                </el-table-column>
                <el-table-column
                    label="角色码"
                    prop="code"
                    width="150"
                ></el-table-column>
                <el-table-column
                    label="角色名"
                    prop="remark"
                    width="180"
                ></el-table-column>
                <el-table-column label="创建时间" width="220">
                    <template #default="{ row }">
                        <el-tag type="primary" effect="light">
                            {{ row.createTime }}
                        </el-tag>
                    </template>
                </el-table-column>
                <el-table-column label="更新时间" width="220">
                    <template #default="{ row }">
                        <el-tag type="primary" effect="light">
                            {{ row.updateTime }}
                        </el-tag>
                    </template>
                </el-table-column>
                <el-table-column label="操作">
                    <template #default="{ row }">
                        <el-button
                            type="primary"
                            size="small"
                            icon="Menu"
                            @click="setRoleItemId(row.id)"
                        >
                            分配权限
                        </el-button>
                        <el-button
                            type="warning"
                            size="small"
                            icon="Edit"
                            @click="updateRole(row.id)"
                        >
                            编辑
                        </el-button>
                        <el-popconfirm
                            width="200"
                            :title="`你确定要删除${row.remark}这一项吗?`"
                            @confirm="removeRole(row.id)"
                        >
                            <template #reference>
                                <el-button
                                    icon="Delete"
                                    type="danger"
                                    size="small"
                                >
                                    删除
                                </el-button>
                            </template>
                        </el-popconfirm>
                    </template>
                </el-table-column>
            </el-table>
        </el-card>
        <el-pagination
            v-model:current-page="pageInfo.page"
            v-model:page-size="pageInfo.limit"
            :page-sizes="[5, 10, 15, 20]"
            small
            layout=" prev, pager, next, jumper,->,sizes, total"
            :total="total"
            @size-change="handleSizeChange"
            @current-change="handleCurrentChange"
        />
        <el-dialog
            v-model="dialogVisible"
            :title="roleItem.id ? '修改角色' : '添加角色'"
            width="30%"
        >
            <el-form
                status-icon
                ref="actionForm"
                :model="roleItem"
                label-width="80"
                :rules="rules"
            >
                <el-form-item prop="id" />
                <el-form-item label="角色码" prop="code">
                    <el-input
                        v-model="roleItem.code"
                        placeholder="请输入角色码"
                    ></el-input>
                </el-form-item>
                <el-form-item label="角色名字" prop="remark">
                    <el-input
                        v-model="roleItem.remark"
                        placeholder="请输入角色名字"
                    ></el-input>
                </el-form-item>
                <el-form-item prop="createTime" />
                <el-form-item prop="updateTime" />
            </el-form>
            <template #footer>
                <el-button @click="closeDialog">取消</el-button>
                <el-button type="primary" @click="handleAddOrUpdate">
                    确认
                </el-button>
            </template>
        </el-dialog>
        <el-drawer
            title="分配权限"
            direction="rtl"
            size="25%"
            :show-close="true"
            :wrapperClosable="true"
            v-model="drawerVisible"
        >
            <el-tree
                ref="treeRef"
                style="max-width: 600px"
                :data="treeData"
                :props="defaultProps"
                show-checkbox
                node-key="id"
                default-expand-all
                highlight-current
                :default-checked-keys="selectPermission"
            />
            <template #footer>
                <div style="flex: auto">
                    <el-button @click="drawerVisible = false">取消</el-button>
                    <el-button type="primary" @click="assignPermissions">
                        确认
                    </el-button>
                </div>
            </template>
        </el-drawer>
    </div>
</template>

<script setup lang="ts" name="Role">
import {
    reqGetPermission,
    reqPermissionByRoleId,
} from '@/api/authority/permission'
import { Tree } from '@/api/authority/permission/type'
import {
    reqAddRole,
    reqAssignPermission,
    reqDeleteRole,
    reqPageRole,
    reqQueryRoleById,
    reqUpdateRole,
} from '@/api/authority/role'
import { Role } from '@/api/authority/role/type'
import { PageInfo } from '@/api/type'
import { resetForm } from '@/utils/elFromUtil'
import { ElMessage, ElTree, FormInstance, FormRules } from 'element-plus'
import { onMounted, reactive, ref } from 'vue'
// 抽屉的显示隐藏
let drawerVisible = ref(false)
// 权限的信息
let treeData = ref<Tree[]>([
    { id: -1, name: '全部权限', code: 'all', children: [] },
])
let selectPermission = ref<number[]>([])
const setRoleItemId = async (id: number) => {
    roleItem.id = id
    drawerVisible.value = true
    await reqGetPermission().then((res) => {
        treeData.value[0].children = res.data
    })
    await reqPermissionByRoleId(roleItem.id).then((res) => {
        let ids = res.data.permissions
        selectPermission.value = ids
    })
}
const defaultProps = {
    children: 'children',
    label: 'name',
}
const treeRef = ref<InstanceType<typeof ElTree>>()
const assignPermissions = () => {
    const halfCheck = treeRef.value!.getHalfCheckedKeys()
    const allCheck = treeRef.value?.getCheckedKeys()
    const permissions = halfCheck
        .concat(allCheck as any)
        .filter((id) => id !== -1)
    reqAssignPermission({
        roleId: roleItem.id,
        permissions: permissions as number[],
    }).then(() => {
        ElMessage.success('分配权限成功')
        drawerVisible.value = false
        roleItem.id = 0
    })
}
// 删除
const removeRole = (id: number) => {
    reqDeleteRole(id).then(() => {
        ElMessage.success('删除成功')
        dialogVisible.value = false
        getRolePage()
    })
}
// 添加或修改
const handleAddOrUpdate = () => {
    actionForm.value?.validate((valid, fields) => {
        if (valid) {
            if (roleItem.id === 0) {
                reqAddRole(roleItem).then(() => {
                    ElMessage.success('添加成功')
                    dialogVisible.value = false
                    getRolePage()
                })
            } else {
                reqUpdateRole(roleItem).then(() => {
                    ElMessage.success('修改成功')
                    dialogVisible.value = false
                    getRolePage()
                })
            }
        } else {
            console.log('submit error', fields)
        }
    })
}
// 编辑
const updateRole = (id: number) => {
    dialogVisible.value = true
    reqQueryRoleById(id).then((res) => {
        Object.assign(roleItem, res.data)
    })
}
// 表单
//表单校验
interface RuleForm {
    code: string
    remark: string
}
const actionForm = ref<FormInstance>()
const checkRoleCode = (rule: any, value: string, callback: any) => {
    // 定义正则表达式,只匹配英文字母和数字
    const pattern = /^[A-Za-z0-9]+$/
    // 如果输入值为空,则通过校验
    if (value === '') {
        callback(new Error('请输入角色码'))
    }
    // 如果输入值不匹配正则表达式,则不通过校验
    else if (!pattern.test(value)) {
        callback(new Error('角色码只能包含英文字母和数字'))
    }
    // 如果输入值匹配正则表达式,则通过校验
    else {
        callback()
    }
}
const rules = reactive<FormRules<RuleForm>>({
    code: [{ required: true, validator: checkRoleCode, trigger: 'blur' }],
    remark: [{ required: true, message: '请输入角色名字', trigger: 'blur' }],
})

// 模态框显示
let dialogVisible = ref(false)
const closeDialog = () => {
    dialogVisible.value = false
    resetForm(actionForm)
}
// 角色增加和编辑
let roleItem = reactive<Role>({
    id: 0,
    code: '',
    remark: '',
})
// 分页数据
let pageInfo = reactive<PageInfo>({
    page: 1,
    limit: 5,
})
let total = ref(0)
const roleName = ref('')
let roleTableData = ref<Role[]>([])
const handleSizeChange = (val: number) => {
    pageInfo.limit = val
    getRolePage()
}
const handleCurrentChange = (val: number) => {
    pageInfo.page = val
    getRolePage()
}
const getRolePage = () => {
    reqPageRole(pageInfo, roleName.value).then((res) => {
        roleTableData.value = res.data.records
        total.value = res.data.total
        pageInfo.page = res.data.current
    })
}

const handleQuery = () => {
    getRolePage()
}
const handleRemoveRoleNameQuery = () => {
    roleName.value = ''
    getRolePage()
}

onMounted(() => {
    getRolePage()
})
</script>

<style lang="less" scoped>
.role-container {
    display: flex;
    flex-direction: column;
    gap: 10px;
    .search-form {
        :deep(.el-form-item) {
            margin-bottom: 0;
            margin-right: 10px;
        }
    }
}
</style>
